package com.atwork.wuhua.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Created by Administrator on 2018/3/12 0012.
 */

public class SPUtils {
    public static final String ISFIRST = "isFirst";//是否是第一次进入APP

    public static final String LONGITUDE = "longitude";//当前位置经度
    public static final String LATITUDE = "latitude";//当前位置纬度
    public static final String ADDRESS_CITY = "latitude_city";//当前位置 市
    public static final String SERVELIST = "serverList";//确认投放的机台
    public static final String SERVAREA = "serverArea";//选择投放的区域
    public static final String SERVDATE = "serverDate";//选择投放的时间
    public static final String SERVCONT_A = "serverContA";//A区选择投放的内容
    public static final String SERVCONT_B = "serverContB";//B区选择投放的内容
    public static final String AD_DATA = "AD_DATA";//我的广告数据
    public static final String NETWORK = "network";//网络状况
    public static final String USER_OBJECT = "userobject"; // 用户基本数据（这是登录之后的数据，有token,openid字段）
    public static final String IS_WAP = "is_wap";//当前位置纬度


    /**
     * 保存在手机里面的文件名
     */
    public static final String FILE_NAME = "trun_data";
    public static final String KEY_SIZE = "_size";
    public static final String str_key = "str_key";// 保存一個String類型

    /**
     * 保存数据
     *
     * @param context
     * @param key
     * @param object
     */
    public static void put(Context context, String key, Object object) {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        if (object instanceof String) {
            editor.putString(key, (String) object);
        } else if (object instanceof Integer) {
            editor.putInt(key, (Integer) object);
        } else if (object instanceof Boolean) {
            editor.putBoolean(key, (Boolean) object);
        } else if (object instanceof Float) {
            editor.putFloat(key, (Float) object);
        } else if (object instanceof Long) {
            editor.putLong(key, (Long) object);
        } else {
            editor.putString(key, (String) object);
        }

        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 通过key获取数据
     *
     * @param context
     * @param key
     * @param defaultObject
     * @return convert to you type
     */
    public static Object get(Context context, String key, Object defaultObject) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);

        if (defaultObject instanceof String) {
            return sp.getString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float) {
            return sp.getFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long) {
            return sp.getLong(key, (Long) defaultObject);
        }

        return null;
    }

    /**
     * 保存对象
     *
     * @param context
     * @param key
     * @param object
     */
    @SuppressLint("NewApi")
    public static void setObject(Context context, String key, Object object) {

        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(baos);
            out.writeObject(object);
            String objectVal = new String(Base64.encode(baos.toByteArray(),
                    Base64.DEFAULT), "UTF-8");
            editor.putString(key, objectVal);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        SharedPreferencesCompat.apply(editor);
    }


    /**
     * 读取对象
     *
     * @param context
     * @param key
     * @param claT
     * @return
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("unchecked")
    public static <T> T getObject(Context context, String key, Class<T> claT) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        if (!contains(context, key)) {
            return null;
        }
        String objectVal = sp.getString(key, null);
        byte[] buffer = Base64.decode(objectVal, Base64.DEFAULT);
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(bais);
            T t = (T) ois.readObject();
            return t;
        } catch (StreamCorruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (bais != null) {
                    bais.close();
                }
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 保存数组
     *
     * @param <T>
     * @param context
     * @param key
     * @param object
     * @param size
     */
    public static void setArray(Context context, String key, List<?> list) {
        int old_size = (Integer) get(context, key + KEY_SIZE, 0);
        int size = list.size();
        put(context, key + KEY_SIZE, size + old_size);
        if (size <= 0) {
            return;
        }
        for (int i = 0; i < size; i++) {
            setObject(context, key + (i + old_size), list.get(i));
        }
    }

    /**
     * 获取数组
     *
     * @param context
     * @param key
     * @param claT
     * @return
     */
    public static <T> List<T> getArray(Context context, String key,
                                       Class<T> claT) {
        int size = (Integer) get(context, key + KEY_SIZE, 0);
        if (size == 0) {
            return null;
        }
        List<T> list = new ArrayList<T>();
        for (int i = 0; i < size; i++) {
            if (contains(context, key + i)) {
                list.add(getObject(context, key + i, claT));
            }
        }
        return list;
    }

    /**
     * 保存数组 (倒序保存) 相当于在index 0位置插入
     * 与getTopArray配套使用
     *
     * @param <T>
     * @param context
     * @param key
     * @param object
     * @param size
     */
    public static void setTopArray(Context context, String key, List<?> list) {
        int old_size = (Integer) get(context, key + KEY_SIZE, 0);
        int size = list.size();
        put(context, key + KEY_SIZE, size + old_size);
        if (size <= 0) {
            return;
        }
        for (int i = 0; i < size; i++) {
            setObject(context, key + (i + old_size), list.get(size - 1 - i));
        }
    }

    /**
     * 获取数组(倒序取出) 即 最后面存的优先取出
     * 与setTopArray配套使用
     *
     * @param context
     * @param key
     * @param claT
     * @return
     */
    public static <T> List<T> getTopArray(Context context, String key,
                                          Class<T> claT) {
        int size = (Integer) get(context, key + KEY_SIZE, 0);
        if (size == 0) {
            return null;
        }
        List<T> list = new ArrayList<T>();
        for (int i = size - 1; i >= 0; i--) {
            if (contains(context, key + i)) {
                list.add(getObject(context, key + i, claT));
            }
        }
        return list;
    }

    /**
     * 移除某个key值已经对应的值
     *
     * @param context
     * @param key
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 移除数组
     *
     * @param context
     * @param key
     */
    public static void removeArray(Context context, String key) {
        int size = (Integer) get(context, key + KEY_SIZE, 0);
        if (size == 0) {
            return;
        }
        remove(context, key + KEY_SIZE);
        for (int i = 0; i < size; i++) {
            remove(context, key + i);
        }
    }

    /**
     * 清除所有数据
     *
     * @param context
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 查询某个key是否已经存在
     *
     * @param context
     * @param key
     * @return
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.contains(key);
    }

    /**
     * 返回所有的键值对
     *
     * @param context
     * @return
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
                Context.MODE_PRIVATE);
        return sp.getAll();
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private static class SharedPreferencesCompat {
        private static final Method sApplyMethod = findApplyMethod();

        /**
         * 反射查找apply的方法
         *
         * @return
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static Method findApplyMethod() {
            try {
                Class clz = SharedPreferences.Editor.class;
                return clz.getMethod("apply");
            } catch (NoSuchMethodException e) {
            }

            return null;
        }

        /**
         * 如果找到则使用apply执行，否则使用commit
         *
         * @param editor
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                if (sApplyMethod != null) {
                    sApplyMethod.invoke(editor);
                    return;
                }
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
            editor.commit();
        }
    }

    public static void setString(Context context, String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(str_key, 0);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        editor.apply();
    }

    public static String getString(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(str_key, 0);
        String str = sp.getString(key, "");
        return str;
    }

}
